package com.eric.middleware.whitelist.aspect;

import com.alibaba.fastjson.JSON;
import com.eric.middleware.whitelist.annotation.DoWhiteList;
import org.apache.commons.beanutils.BeanUtils;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.lang.reflect.Method;

@Aspect
@Component
public class DoJoinPoint {
    private Logger logger = LoggerFactory.getLogger(DoJoinPoint.class);

    @Resource
    private String whiteListConfig;

    @Pointcut("@annotation(com.eric.middleware.whitelist.annotation.DoWhiteList)")
    public void whiteList() {
    }

    @Around("whiteList()")
    public Object doRouter(ProceedingJoinPoint joinPoint) throws Throwable {
        Method method = getMethod(joinPoint);
        // 获取当前注解
        DoWhiteList doWhiteList = method.getAnnotation(DoWhiteList.class);
        // 获取字段值
        String keyValue = getFiledValue(doWhiteList.key(), joinPoint.getArgs());
        logger.info("middleware whitelist handler method：{} value：{}", method.getName(), keyValue);

        if (null == keyValue || "".equals(keyValue)) {
            return joinPoint.proceed();
        }

        String[] split = whiteListConfig.split(",");
        // 白名单过滤
        for (String str : split) {
            if (keyValue.equals(str)) {
                return joinPoint.proceed();
            }
        }
        // 拦截
        return returnObject(doWhiteList, method);
    }

    /**
     * 返回对象
     *
     * @param whiteList 白名单
     * @param method    方法
     * @return 响应结果
     */
    private Object returnObject(DoWhiteList whiteList, Method method) throws IllegalAccessException, InstantiationException {
        Class<?> returnType = method.getReturnType();
        String returnJson = whiteList.returnJson();
        if ("".equals(returnJson)) {
            return returnType.newInstance();
        }
        return JSON.parseObject(returnJson, returnType);
    }

    /**
     * 获取method
     *
     * @return method 获取方法
     */
    private Method getMethod(ProceedingJoinPoint joinPoint) throws NoSuchMethodException {
        MethodSignature methodSignature = (MethodSignature) joinPoint.getSignature();
        // 获取join point作用的方法
        return joinPoint.getTarget().getClass().getMethod(methodSignature.getName(), methodSignature.getParameterTypes());
    }

    /**
     * 获取属性值
     *
     * @param filed 字段
     * @param args  参数
     * @return 属性值
     */
    private String getFiledValue(String filed, Object[] args) {
        String filedValue = null;
        try {
            for (Object arg : args) {
                filedValue = BeanUtils.getProperty(arg, filed);
            }
        } catch (Exception e) {
            if (args.length == 1) {
                return args[0].toString();
            }
        }
        return filedValue;
    }
}